home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 147
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin
/
tools
/
ask
/
askden
/
source
/
den2var.s
< prev
Wrap
Text File
|
1999-04-05
|
11KB
|
473 lines
******************************************************************************
* ASK3アクセサリ ASKDen V2以降用 変数ダンププログラム
* Copyright 1998-99 by AIG-Soft
******************************************************************************
.include defines.mac
.include fefunc.mac * 整数/実数演算を使う
.include pspdef.mac
.cpu 68000
******************************************************************************
* 常駐チェックid(ASKDen2と同じ位置に置く)
******************************************************************************
.text
.even
KEEP_START:
* 常駐確認用識別子
varad .dc.l 0 * ASKDen2はここにvarのアドレスが入っている
id: .dc.b 'ASKDen V2',0
******************************************************************************
* 定数表
******************************************************************************
Yuketa equ 6 * 32ビット単精度実数の有効桁数
* 実験の結果より6桁なら大丈夫らしい
* 変数関係
VTYPE equ %1_1111 * 変数型(32種類)
VKAKU equ BIT7 * 0=確定 , 1=未確定
VDAI equ BIT6 * 0=再代入可 , 1=不可
BVDAI equ 6 * VDAIのビット番号
V_INT equ 0 * 0=整数数値(すべての演算可能)
V_FLOAT equ 1 * 1=単精度実数
*
VTOP equ 2 * 変数格納先頭位置:ハッシュの関係で0は使えない
.offset 0
* 変数構造体
vwork .ds.l 1 * unchar *vwork ワークエリア先頭アドレス(初期値は0=確保してない)
vwsize .ds.l 1 * long vwsize
vpoint .ds.l 1 * long vpoint 変数格納先頭位置:ハッシュの都合で0は使えない
vlots .ds.l 1 * long vlots
vhash .ds.l 1 * long *vhash
vhsize .ds.w 1 * unsint vhsize
vlmax .ds.w 1 * unsint vlmax 変数名最大長
mode .ds.w 1 * unsint mode
.offset 0
* 変数格納オフセット
* len mode num name[00]
* 1 1 4 len+1 size
* 0 1 2 6 6+len+1 offset
Vlen .ds.b 1
Vmd .ds.b 1
Vnum .ds.l 1
Vname
.text
sizeV equ Vname * len+mode+numのサイズ
******************************************************************************
ctol:
* long ctol(adrs)
* d0,a0破壊
move.l 4(sp),d0
move.l d0,a0
btst.l #0,d0
bne 1f
* 偶数アドレス = 直接読み出来る
move.l (a0),d0
rts
1: * 奇数アドレス = 直接読み出来ない
move.l 1(a0),d0 * 次のアドレスからH.L/L.H/L.L/DUMMYを読み取る
move.b (a0),d0
ror.l #8,d0
rts
******************************************************************************
make_base:
* 2/8/10/16進数文字列作成(整数のみ)
* 一番長くなるのは2進数で32ビット分=32バイト+符号
* base >0 : 正で処理 , base < 0 : 符号つきで処理
* int make_base(int code,unchar dec[2+BINT+1],int base)
ofs = (4*2)
regs .reg d3/d4
movem.l regs,-(sp)
move.l ofs+4(sp),d0 * num(unsigned)<-code
moveq.l #32+2,d3 * i
moveq.l #0,d2 * sign=0(.wでいい)
move.l ofs+12(sp),d1 * base<0?
bpl 1f * No
* base<0 : 符号付き
tst.l d0 * code<0?
bpl 2f * No
* code<0
neg.l d0 * num=-code
beq 2f * num==0? Yes
* num!=0
moveq.l #1,d2 * sign=1
2: neg.l d1 * base=-base
*
1: move.l ofs+8(sp),a0 * dec
lea (a0,d3.l),a0 * dec[i]
clr.b (a0) * =EOS
lea b(pc),a1 * b[]
3: cmp.l d1,d0 * num>=base?
bcs 4f * No
move.l d0,d4
FPACK __UMOD * d4.l=num%base d0%=d1(符号なし)
exg d0,d4
move.b (a1,d4.l),-(a0) * dec[--i]=b[num%base];
subq.l #1,d3 * --i
FPACK __UDIV * num/=base d0/=d1(符号なし)
bra 3b
*
4: move.b (a1,d0.l),-(a0) * dec[--i]=b[num]
subq.l #1,d3 * --i
tst.w d2 * sign==1?
beq @f * No
move.b #'-',-(a0) * 負号
subq.l #1,d3 * --i
@@: move.l d3,d0 * return(i)
movem.l (sp)+,regs
rts
*
b .dc.b '0123456789ABCDEF',0
.even
******************************************************************************
var_dump:
* 変数領域ダンプ
* void var_dump(&var)
* ASKDen2のそれと全く同じではない
regs .reg d3-d6/a3-a4
ofs = (4*(4+2))
movem.l regs,-(sp)
move.w base(pc),d0
lea bases(pc),a0 * その時の表示進数に従う
moveq.l #0,d4 * for .b = .l
move.b (a0,d0.w),d4 * bs=bases[base]
moveq.l #0,d6 * for .b = .w
lea Bsym(pc),a0
move.b (a0,d0.w),d6 * $%@
*
move.l 4+ofs(sp),a0 * varのアドレス
move.l vlots(a0),d3 * vlots
bne @f * 変数はある
* 変数がない
bsr PrCRLF
pea MesNoVar(pc)
DOS _PRINT
addq.l #4,sp
bra 7f
*
@@: move.l vwork(a0),a3 * vwork
addq.l #VTOP,a3 * &vwork[VTOP]
*
5: bsr PrCRLF * 改行
pea Vname(a3) * vname
DOS _PRINT * 変数名
addq.l #4,sp
bsr PrTAB
*
pea Vnum(a3)
bsr ctol * d0.l=num
addq.l #4,sp
move.l d0,d5
*
move.b Vmd(a3),d0 * md
moveq.l #VKAKU,d1
and.b d0,d1
beq @f * 確定
* 未確定
pea MesMikaku(pc)
bra 6f
*
@@: * 確定
clr.b eover * エラー無しの印
lea MesDeni(pc),a4
and.b #VTYPE,d0
beq v2 * 整数
* 実数
lea MesDenf(pc),a4
cmp.l #10,d4 * 10進数?
bne @f * No
* 実数10進表示
lea work(pc),a0 * 流用
move.l d5,d0 * num
moveq.l #Yuketa,d2 * 全体の桁数
FPACK __FGCVT
pea work(pc)
bra 6f * 表示へ
*
@@: * 実数10進以外
tst.b fnai
bne v2 * 内部表現表示
* 整数化表示
move.l d5,d0
FPACK __FTOL * float(d0) -> int(d0)
scs.b eover * 整数化出来ないの印
bcs v2 * 整数化出来ない時はしない
@@: move.l d0,d5
*
v2: * 整数はいきなりここへ来る
move.l d4,-(sp) * 表示進数
pea work(pc) * workを流用
move.l d5,-(sp) * num
bsr make_base * ret=d0
lea 4*3(sp),sp
lea work(pc),a0
add.l d0,a0 * &work[ret]
* 進数記号表示
cmp.l #10,d4
beq @f
move.w d6,-(sp)
DOS _PUTCHAR * d6.bのみ表示される
addq.l #2,sp
@@: pea (a0)
6: DOS _PRINT * 数値表示
bsr PrTAB
pea (a4) * 整数/実数
DOS _PRINT
addq.l #8,sp
*
tst.b eover * 整数化出来てる?
beq @f
* 整数化出来てない
move.w #'(',-(sp)
DOS _PUTCHAR
pea MVARCCINT(pc)
DOS _PRINT * "(整数化出来ない)"を表示
move.w #')',-(sp)
DOS _PUTCHAR
addq.l #8,sp
@@: *
btst.b #BVDAI,Vmd(a3) * md&VDAI?
beq @f
bsr PrTAB
pea MesTeisu(pc) * 定数=再代入不可
DOS _PRINT
addq.l #4,sp
@@: *
moveq.l #0,d0 * for .b=.l
move.b (a3)+,d0 * len
addq.l #sizeV,d0 * len(1):md(1):num(4):vname(len):EOS
add.l d0,a3 * 次の変数へ
*
subq.l #1,d3 * 変数がある間
bne 5b
*
bsr PrCRLF * 最後の改行
7: movem.l (sp)+,regs
rts
PrTAB:
move.w #TAB,-(sp)
DOS _PUTCHAR * TAB
addq.l #2,sp
rts
PrCRLF:
pea CrLf(pc)
DOS _PRINT * 改行
addq.l #4,sp
rts
******************************************************************************
* この中ではa0/a2は壊さないこと(プロセス管理ポインタ/コマンドラインを参照するため)
AMAX equ 10 * 最大引数数
* コマンドライン
* a2
* 0(a2) = コマンドライン長
* 1(a2)~ = コマンドライン
* '-? ',0 スペース/タブはそのまま
*
GetArgv:
* コマンドラインを解析して各要素の先頭アドレスをargvに、個数をargcに格納する
* 引数:a2 = コマンドライン
* 出力:d0.w = 引数数(=argc)
* 破壊:d0-d1
regs .reg a2/a6
movem.l regs,-(sp)
moveq.l #0,d1 * 引数数
tst.b (a2)+ * コマンドライン長を飛ばす
beq 2f * コマンドライン長=0 -> 引数なし
lea argv(pc),a6
@@: * SPC/TAB skip
move.b (a2)+,d0
beq 2f * コマンドライン終わり
cmp.b #SPC,d0 * skip SPC
beq @b
cmp.b #TAB,d0 * skip TAB
beq @b
* SPC/TAB以外の文字が有った
subq.l #1,a2
move.l a2,(a6)+ * argv記録
addq.w #1,d1 * 引数+1
cmp.w #AMAX,d1 * 最大数を越える?
bcc 2f * -> 越える
1: * 次のEOS/SPC/TABまで飛ばす
move.b (a2)+,d0
beq 2f * コマンドライン終わり
cmp.b #SPC,d0 * skip SPC
beq @b
cmp.b #TAB,d0 * skip TAB
bne 1b
bra @b
*
2: move.w d1,argc * 記録
move.w d1,d0
movem.l (sp)+,regs
rts
*---------------------------------------------
CheckOption:
* コマンドラインから指定オプションを探す
* 必ずGetArgvを呼び出した後に使うこと
* オプション名は先頭1文字だけで判別
* 引数:d2.b = オプション名(英小文字1文字/大文字の時は直後の文字列をa6に転送)
* a6.l = 直後文字列転送エリアアドレス
* 出力:d0.l = 0:なし , !=0:そのオプションの次のアドレス
* 破壊:d0-d1
regs .reg d7/a4-a6
movem.l regs,-(sp)
moveq.l #0,d7 * 後ろ引数取り込まない
cmp.b #'a',d2 * オプション名'a'>=?
bcc @f * Yes
moveq.l #1,d7 * 英大文字;後ろ引数取り込む
or.b #$20,d2 * 小文字化
*
@@: move.w argc(pc),d1
beq 1f * 引数はない
subq.w #1,d1 * -1 for dbra
lea argv(pc),a4
@@: move.l (a4)+,a5 * argv[i]
move.b (a5)+,d0 * argv[i][0]
* オプションの1文字目は'/''-'
cmp.b #'/',d0
beq 2f
cmp.b #'-',d0
beq 2f
3: dbra d1,@b * 次へ
1: * (指定)オプションはない
moveq.l #0,d0
bra 4f
2: * '/''-'があった
move.b (a5)+,d0 * 次の1文字
or.b #$20,d0 * 英小文字化
cmp.b d2,d0 * 一致?
bne 3b * -> 不一致
move.l a5,d0 * オプション名の次のアドレス(!=0)
tst.w d7 * 後ろ取り込む?
beq 4f * No
* 後ろ引数の取り込み -> a6
* d0=a5 ; オプション名の次のアドレス(!=0)
@@: move.b (a5)+,d1
beq 5f * EOS
cmp.b #SPC,d1
beq 5f
cmp.b #TAB,d1 * EOS/SPC/TABまで
beq 5f
move.b d1,(a6)+
bra @b
*
5: clr.b (a6) * EOS
4: movem.l (sp)+,regs
rts
******************************************************************************
* メイン
******************************************************************************
.xref Atoi
.xref keepchk2
main:
move.l #(id-KEEP_START),-(sp) * 識別子の相対位置
pea.l (a0) * 自分のメモリ管理ポインタ
bsr keepchk2 * 常駐チェック -> d0.b , a0.l
addq.l #4*2,sp
tst.b d0
bne ok * 常駐してる
* 常駐してない; エラー終了
pea MesNoKeep(pc)
DOS _PRINT
** addq.l #4,sp
move.w #2,-(sp) * exit(2)
DOS _EXIT2
*
ok: lea varad-KEEP_START+PSPSIZ(a0),a4 * varadのアドレス
*
bsr GetArgv * argc/argv設定
*
* 引数チェック
moveq.l #'p',d2 * -p : 表示符号あり
bsr CheckOption
tst.l d0
seq hugo * -pなし=符号あり
*
moveq.l #'n',d2 * -n : 内部表記する・しない
bsr CheckOption
tst.l d0
sne fnai * -nあり=内部表記する
*
lea work(pc),a6
moveq.l #'S',d2 * -Smode : 表示進数[mode=0,1,2,3]
bsr CheckOption
move.l #0,d2 * デフォルト:10進数
tst.l d0
beq @f * 指定なし
* 指定あり : モード読み取り
bsr Atoi * 読み取り -> d0.l (d0/d1/a6破壊)
* サイズ判定
cmp.l #3,d0
bhi @f * >3は0とみなす
tst.l d0
bmi @f * <0も0とみなす
move.l d0,d2
@@: move.w d2,base
*
sub.l a0,a0
IOCS _B_SUPER * スーパーバイザーモードへ
move.l d0,-(sp)
*
move.l (a4),-(sp) * 常駐しているプロセス内のvarアドレス
bsr var_dump
addq.l #4,sp
*
move.l (sp)+,d0
beq @f * 元がスーパーバイザーモードである
move.l d0,a1
IOCS _B_SUPER
*
@@: clr.w -(sp)
DOS _EXIT2 * 正常終了
******************************************************************************
* メッセージ&ワーク
******************************************************************************
MesNoKeep: .dc.b '対応するASKDen2が常駐していません',CR,LF,0
MVARCCINT .dc.b '整数化出来ない',0
MesNoVar: .dc.b '変数はありません' * CrLfに続く
CrLf: .dc.b CR,LF,0
MesMikaku: .dc.b '[未確定]',0
MesTeisu: .dc.b '[定数]',0
MesDeni: .dc.b '整数',0
MesDenf: .dc.b '実数',0
Bsym .dc.b ' $%@',0 * 進数シンボル(baseの順)
.even
argc .ds.w 1 * 引数の個数
argv .ds.l AMAX * 各引数の先頭アドレス
var .ds.l 1 * 変数構造体のアドレス
work .ds.b 96 * 数値などのバッファー
eover .dc.b 1 * エラーフラグ
.even
bases .dc.b 10,16,2,8 * 進数テーブル
base: .dc.w 0 * 10進数(bases[base])
hugo .dc.b $ff * 0=符号なし,$ff=符号有り
fnai .dc.b 0 * 0=整数化,$ff=内部表現
******************************************************************************
.end main